package us.versus.them.b3ge.minigames.cards;

import us.versus.them.b3ge.minigames.cards.Card;

class Deck {
	var current:Int;
	var cards : Array< Card >;

	public function new() {
		current = 0;
		cards = new Array< Card >();
		for ( suit in [ Suit.Hearts, Suit.Diamonds, Suit.Clubs, Suit.Spades ] ) {
			for ( i in 1 ... 14 ) {
				cards.push( new Card( suit, i ) );
			}
		}
	}

	public function shuffle() {
		this.current = 0;
		for ( i in 0 ... cards.length ) {
			var a = Std.int( Math.random() * cards.length );
			var b = Std.int( Math.random() * cards.length );
			var tmp = cards[ a ];
			cards[ a ] = cards[ b ];
			cards[ b ] = tmp;
		}
	}

	public function next() : Card {
		return if ( this.current < this.cards.length ) {
			var card = this.cards[ this.current++ ];
			card.used = false;
			card;
		} else {
			null;
		}
	}

	public function cardsRemaining() : Int {
		return 52 - this.current;
	}

	// throws exception if not enuff cards
	public function checkCardsNeeded( numberOfHands:Int, numberOfCards:Int ) {
		this.checkCardsRemaining( numberOfCards * numberOfHands );
	}

	// throws exception if not enuff cards
	public function checkCardsRemaining( cardsNeeded:Int ) {
		if ( cardsNeeded > this.cardsRemaining() ) {
			throw (
				"not enuff cards to make that deal: " 
				+ this.cardsRemaining 
				+ " versus "
				+ cardsNeeded
			);
		}
	}

	// throws exception if not enuff cards
	public function deal( numberOfHands:Int, numberOfCards:Int ) : Array< Array< Card > > {
		this.checkCardsNeeded( numberOfHands, numberOfCards );

		var hands = new Array< Array< Card > >();
		for ( i in 0 ... numberOfHands ) {
			var hand = new Array< Card >();
			for ( j in 0 ... numberOfCards ) {
				hand.push( this.next() );
			}
			hands.push( hand );
		}
		return hands;
	}

	// throws exception if not enuff cards
	public function dealHand( numberOfCards:Int ) : Array< Card > {
		return this.deal( 1, numberOfCards )[ 0 ];
	}
}
